package com.jeedcp.core.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeedcp.core.aspect.annotation.LogOperationAno;
import com.jeedcp.core.common.JsonResult;
import com.jeedcp.core.common.PageUtils;
import com.jeedcp.core.query.QueryViewVo;
import com.jeedcp.core.service.BaseService;
import com.jeedcp.core.util.ConvertUtils;
import com.jeedcp.core.util.ExcelUtils;
import com.jeedcp.core.validator.Assert;
import com.jeedcp.core.validator.ValidatorUtils;
import com.jeedcp.core.validator.group.AddGroup;
import com.jeedcp.core.validator.group.DefaultGroup;
import com.jeedcp.core.validator.group.UpdateGroup;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.ParameterizedType;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @project: jeedcp
 * @description: 增删改查通用管理功能-父类
 * @author: caochaofeng
 * @create: 2019-08-15 09:03
 */
@RestController
@Slf4j
public abstract class BaseController<Service extends BaseService<T>, T, D> {

    @Autowired
    protected Service baseService;

    protected Class<D> getDClass() {
        Class<D> dc = (Class<D>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[2];
        return dc;
    }

    protected Class<T> getTClass() {
        Class<T> tClass = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[1];
        return tClass;
    }


    @GetMapping("/list" )
    @ApiOperation("高级分页" )
    public JsonResult<PageUtils<D>> list(QueryViewVo<T> queryViewVo) {
        IPage<T> iPage = baseService.queryPage(queryViewVo);
        List<D> targetList = ConvertUtils.sourceToTarget(iPage.getRecords(), getDClass());
        PageUtils<D> page = new PageUtils<D>(targetList, (int) iPage.getTotal(), (int) iPage.getSize(), (int) iPage.getCurrent());
        return new JsonResult<PageUtils<D>>().ok(page);
    }

    protected <T> PageUtils<T> getPageData(IPage page, Class<T> target) {
        List<T> targetList = ConvertUtils.sourceToTarget(page.getRecords(), target);
        return new PageUtils<T>(targetList, (int) page.getTotal(), (int) page.getSize(), (int) page.getCurrent());
    }

    @GetMapping("{id}" )
    @ApiOperation("信息" )
    public JsonResult<D> get(@PathVariable("id" ) String id) {
        T entity = (T) baseService.getById(id);
        D data = ConvertUtils.sourceToTarget(entity, getDClass());
        return new JsonResult<D>().ok(data);
    }

    @PostMapping
    @ApiOperation("保存" )
    @LogOperationAno("保存" )
    public JsonResult save(@RequestBody D dto) {
        //效验数据
        ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class);
        T entity = ConvertUtils.sourceToTarget(dto, getTClass());
        baseService.save(entity);
        return new JsonResult();
    }

    @PutMapping
    @ApiOperation("修改" )
    @LogOperationAno("修改" )
    public JsonResult update(@RequestBody D dto) {
        //效验数据
        ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class);
        T entity = ConvertUtils.sourceToTarget(dto, getTClass());
        baseService.updateById(entity);
        return new JsonResult().ok("修改成功" );
    }

    @DeleteMapping
    @ApiOperation("删除" )
    @LogOperationAno("删除" )
    public JsonResult delete(@RequestBody String[] ids) {
        //效验数据
        Assert.isArrayEmpty(ids, "id" );

        baseService.removeByIds(Arrays.asList(ids));

        return new JsonResult().ok("删除成功" );
    }

    @GetMapping("export" )
    @ApiOperation("导出" )
    @LogOperationAno("导出" )
    public void export(QueryViewVo<T> queryViewVo, HttpServletResponse response) throws Exception {
        IPage<T> page = baseService.queryPage(queryViewVo);
        ExcelUtils.exportExcelToTarget(response, null, page.getRecords(), getDClass());
    }

    protected D convertEntity2Dto(T entity) {
        D data = ConvertUtils.sourceToTarget(entity, getDClass());
        return data;
    }

    protected T convertDto2Entity(D dto) {
        T entity = ConvertUtils.sourceToTarget(dto, getTClass());
        return entity;
    }


    protected List<D> convertEntityList2DtoList(List<T> entityList) {
        List<D> targetList = ConvertUtils.sourceToTarget(entityList, getDClass());
        return targetList;
    }


}
